// client project main.go
package main

import (
	"bufio"
	"bytes"
	"encoding/gob"
	"fmt"
	_ "image/jpeg"
	"log"
	"mustang"
	"mustang/mouse"
	"net"
	"net/http"
	"net/rpc"
	"os"

	"github.com/whtang/GoRTP/rtp"
)

var (
	quit                       chan int
	clientPort, controllerPort int
	controller, client         *net.IPAddr
	img                        []byte
)

func init() {
	quit = make(chan int)
	clientPort = 11110
	controllerPort = 12110
	client, _ = net.ResolveIPAddr("ip", "127.0.0.1")
	controller, _ = net.ResolveIPAddr("ip", "127.0.0.1")
	loadImage()
}

func loadImage() {
	file, _ := os.Open("lenna.jpg")
	defer file.Close()
	var buf bytes.Buffer
	bufio.NewReader(file).WriteTo(&buf)
	img = buf.Bytes()
}

func setUpRTP() (tp *rtp.TransportUDP, rs *rtp.Session) {
	tp, _ = rtp.NewTransportUDP(client, clientPort)
	rs = rtp.NewSession(tp, tp)
	rs.AddRemote(&rtp.Address{controller.IP, controllerPort, controllerPort + 1})
	strClientIdx, _ := rs.NewSsrcStreamOut(&rtp.Address{client.IP, clientPort, clientPort + 1}, 10203040, 1234)
	rs.SsrcStreamOutForIndex(strClientIdx).SetPayloadType(0)
	return
}

func sendPic() {
	var stamp uint32
	_, rs := setUpRTP()
	rs.StartSession()
	log.Println("img size: ", len(img))

	var buf bytes.Buffer
	encoder := gob.NewEncoder(&buf)

	for {
		for packet := range mustang.GetPackets(img, 1100) {
			rp := rs.NewDataPacket(stamp)
			err := encoder.Encode(*packet)
			if err != nil {
				log.Fatalln(err)
			}
			rp.SetPayload(buf.Bytes())
			//log.Println("sent one packet, length: ", len(rp.Payload()))
			stamp += uint32(len(rp.Payload()))
			rs.WriteData(rp)
			rp.FreePacket()
			buf.Reset()
		}
		log.Println("sent one pic")
	}
}

func stop() {
	log.Println("stop function")
}

func main() {
	log.Println("system go")
	go sendPic()

	m := new(mouse.RPCMouse)
	rpc.Register(m)
	rpc.HandleHTTP()
	l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", mustang.Client, mustang.ClientRPCPort))
	if err != nil {
		log.Fatalln(err)
	}
	go http.Serve(l, nil)
	log.Println("rpc server start work now")

	// todo need remove
	//	time.AfterFunc(time.Second*10, func() {
	//		quit <- 1
	//	})

	<-quit
	stop()
	log.Println("system down")
}
